package com.aratana.ui.table.render;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.Date;

import javax.swing.AbstractButton;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.JTextComponent;

import com.aratana.ui.fields.BasicField;
import com.aratana.ui.fields.DateField;
import com.aratana.ui.fields.MoneyField;

@SuppressWarnings("serial")
public class ColorRender extends DefaultCellEditor implements TableCellRenderer {

	private static Color color;

	private static Border selectText = new EmptyBorder(0, 0, 0, 4) {

		@Override
		public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
			super.paintBorder(c, g, x, y, width, height);
			g.setColor(color);
			g.drawRect(x, y, width - 1, height - 1);
		}
	};

	private static Border select = new EmptyBorder(0, 0, 0, 0) {

		@Override
		public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
			super.paintBorder(c, g, x, y, width, height);
			g.setColor(color);
			g.drawRect(x, y, width - 1, height - 1);
		}
	};

	private static Border emptyText = new EmptyBorder(0, 4, 0, 0);

	private static Border empty = new EmptyBorder(0, 0, 0, 0);

	private final JComponent component;

	private boolean adjust = true;

	public ColorRender(final JCheckBox checkBox) {
		super(checkBox);
		checkBox.setHorizontalAlignment(SwingConstants.CENTER);
		checkBox.setBorderPainted(true);
		component = checkBox;
	}

	public ColorRender(final JComboBox comboBox) {
		super(comboBox);
		component = comboBox;
	}

	public ColorRender(final JTextField textField) {
		super(textField);
		component = textField;
	}

	private void adjustComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final boolean editor) {
		if (isSelected && !editor) {
			component.setBackground(table.getSelectionBackground());
			component.setForeground(color = table.getSelectionForeground());
		} else {
			component.setForeground(table.getForeground());
			if (row % 2 == 0 && !table.isPaintingForPrint()) {
				component.setBackground(new Color(235, 235, 235));
			} else {
				component.setBackground(Color.WHITE);
			}
		}

		setValue(value);
		component.setBorder(component instanceof JTextComponent ? hasFocus ? selectText : emptyText : hasFocus ? select : empty);
		adjust = !adjust;
		if (!editor && component instanceof JTextComponent) {
			final String text = ((JTextComponent) component).getText().trim();
			if (!text.isEmpty()) {
				component.setToolTipText(text + (adjust ? "" : "\0"));
			} else {
				component.setToolTipText(null);
			}
		}
	}

	@Override
	public Object getCellEditorValue() {
		Object retorno = null;
		if (component instanceof BasicField<?>) {
			retorno = ((BasicField<?>) component).getValue();
		} else if (component instanceof JTextComponent) {
			retorno = ((JTextComponent) component).getText();
		} else if (component instanceof AbstractButton) {
			retorno = ((AbstractButton) component).isSelected();
		}
		return retorno;
	}

	@Override
	public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected, final int row, final int column) {
		adjustComponent(table, value, isSelected, false, row, true);
		return component;
	}

	@Override
	public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
		adjustComponent(table, value, isSelected, hasFocus, row, false);
		return component;
	}

	public void setValue(final Object value) {
		if (component instanceof DateField) {
			if (value instanceof Date) {
				((DateField) component).setValue((Date) value);
			} else {
				((DateField) component).setText(value != null ? value.toString() : null);
			}
		} else if (component instanceof MoneyField) {
			if (value instanceof Double) {
				((MoneyField) component).setValue((Double) value);
			} else {
				((MoneyField) component).setText(value != null ? value.toString() : null);
			}
		} else if (component instanceof JTextComponent) {
			((JTextComponent) component).setText(value != null ? value.toString() : null);
		} else if (component instanceof AbstractButton) {
			((AbstractButton) component).setSelected(value != null ? Boolean.parseBoolean(value.toString()) : Boolean.FALSE);
		}
	}
}
